{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.models import Sequential\n",
    "from keras.layers import LSTM,Dropout\n",
    "from keras.layers import Dense\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn import decomposition\n",
    "from sklearn.feature_selection import SelectKBest\n",
    "from sklearn.feature_selection import chi2\n",
    "from sklearn.pipeline import FeatureUnion\n",
    "from sklearn.model_selection import StratifiedKFold\n",
    "import matplotlib.pyplot as plt\n",
    "import scikitplot as skplt\n",
    "from sklearn.preprocessing import label_binarize\n",
    "from sklearn.metrics import roc_curve, auc\n",
    "from scipy import interp\n",
    "from itertools import cycle\n",
    "import time\n",
    "from keras import metrics\n",
    "from keras import optimizers\n",
    "from keras import initializers\n",
    "from keras.callbacks import ModelCheckpoint\n",
    "import pprint\n",
    "from keras.callbacks import Callback"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "kdd_dataset = pd.read_csv('KDD.preProcessed.csv')\n",
    "kdd_dataset.head()\n",
    "#kdd_dataset.dropna()\n",
    "np.random.seed(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "columns = list(kdd_dataset)\n",
    "features = columns\n",
    "features.remove('label_DoS')\n",
    "features.remove('label_Normal')\n",
    "features.remove('label_Probe')\n",
    "features.remove('label_R2L')\n",
    "features.remove('label_U2R')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "DoS = kdd_dataset.loc[kdd_dataset['label_DoS'] == 1]\n",
    "Normal = kdd_dataset.loc[kdd_dataset['label_Normal'] == 1]\n",
    "Probe = kdd_dataset.loc[kdd_dataset['label_Probe'] == 1]\n",
    "R2L = kdd_dataset.loc[kdd_dataset['label_R2L'] == 1]\n",
    "U2R = kdd_dataset.loc[kdd_dataset['label_U2R'] == 1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'\\nDoS = DoS.sample(n=100000,random_state = 42)\\nNormal = Normal.sample(n=100000, random_state = 42)\\nProbe = Probe.sample(n=40000, random_state=42)\\nR2L = R2L.sample(n=1126, random_state=42)\\n'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "DoS = DoS.sample(n=1000,random_state = 42)\n",
    "Normal = Normal.sample(n=1000, random_state = 42)\n",
    "Probe = Probe.sample(n=1000, random_state=42)\n",
    "R2L = R2L.sample(n=1126, random_state=42)\n",
    "'''\n",
    "DoS = DoS.sample(n=100000,random_state = 42)\n",
    "Normal = Normal.sample(n=100000, random_state = 42)\n",
    "Probe = Probe.sample(n=40000, random_state=42)\n",
    "R2L = R2L.sample(n=1126, random_state=42)\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#U2R = U2R.append([U2R]*500,ignore_index=True)\n",
    "#R2L = R2L.append([R2L]*100,ignore_index=True)\n",
    "#DoS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "reduced_dataset = pd.concat([DoS,Normal,Probe,R2L,U2R])\n",
    "kdd_dataset = reduced_dataset.sample(n=len(reduced_dataset), random_state = 42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "number of datapoints = 4148 and number of features = 53\n"
     ]
    }
   ],
   "source": [
    "\n",
    "x = kdd_dataset[features].values\n",
    "y = kdd_dataset.iloc[:,53:].values\n",
    "print(\"number of datapoints = {} and number of features = {}\".format(len(x),len(x[0])))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Counter({(0.0, 0.0, 0.0, 1.0, 0.0): 1126, (0.0, 0.0, 1.0, 0.0, 0.0): 1000, (0.0, 1.0, 0.0, 0.0, 0.0): 1000, (1.0, 0.0, 0.0, 0.0, 0.0): 1000, (0.0, 0.0, 0.0, 0.0, 1.0): 22})\n"
     ]
    }
   ],
   "source": [
    "# Counting occurrences\n",
    "from collections import Counter\n",
    "print(Counter([tuple(x) for x in y]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Shape before transformation - (4148, 53)\n",
      "Shape after transformation - (4148, 10)\n"
     ]
    }
   ],
   "source": [
    "#PCA\n",
    "\n",
    "print(\"Shape before transformation - {}\".format(np.asarray(x).shape))\n",
    "pca = decomposition.PCA(n_components=10)\n",
    "pca.fit(x)\n",
    "x_pca = pca.transform(x)\n",
    "print(\"Shape after transformation - {}\".format(x_pca.shape))\n",
    "x_pca = x_pca.tolist()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "X_tr, X_val, Y_tr, Y_val = train_test_split(x_pca, y,\n",
    "                                                    stratify=y, \n",
    "                                                    test_size=0.2,\n",
    "                                                    random_state=42)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X_train, X_test, Y_train, Y_test = train_test_split(X_tr, Y_tr,\n",
    "                                                    stratify=Y_tr, \n",
    "                                                    test_size=0.25,\n",
    "                                                    random_state=42)\n",
    "max_len = len(X_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def processTrainTestArrays(x,y):\n",
    "    x=np.asarray(x)\n",
    "    y=np.asarray(y)\n",
    "    \n",
    "    x = np.reshape(x, (x.shape[0], x.shape[1],1))\n",
    "    Y_temp = [[item]*10 for item in y]\n",
    "    y = np.reshape(np.asarray(Y_temp),(x.shape[0]*10,5))\n",
    "    #y = [[item]*10 for item in y]\n",
    "    \n",
    "    #y = [np.argmax(item) for item in y]\n",
    "    #y = np.reshape(y, (y.shape[0], 1))\n",
    "\n",
    "\n",
    "    return x,y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def onehotencode(y):\n",
    "    #from keras.utils.np_utils import to_categorical\n",
    "    #y_binary = to_categorical(y)\n",
    "    y = [int(item) for item in y]\n",
    "    targets = np.array(y).reshape(-1)\n",
    "    y_binary = np.eye(5)[targets]\n",
    "    \n",
    "    return y_binary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# define model\n",
    "#length = len(kdd_dataset)\n",
    "def create_model(X_train,Y_train, number_of_units):\n",
    "    Batch_size = 1\n",
    "    randomInit = initializers.RandomUniform(seed=42)\n",
    "    nadam = optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)\n",
    "    \n",
    "    model = Sequential()\n",
    "    #model.add(LSTM(number_of_units, kernel_initializer = randomInit, bias_initializer = randomInit, stateful = True,\n",
    "    #               batch_input_shape=(Batch_size,X_train.shape[1], X_train.shape[2]),return_sequences=True))\n",
    "    model.add(LSTM(number_of_units, kernel_initializer = randomInit, bias_initializer = randomInit, stateful = True,\n",
    "                   batch_input_shape=(Batch_size,1,1),return_sequences=False))\n",
    "    \n",
    "    #model.add(Dropout(0.1))\n",
    "    #model.add(LSTM(number_of_units, kernel_initializer = randomInit, bias_initializer = randomInit, stateful = True,\n",
    "    #               batch_input_shape=(Batch_size,X_train.shape[1], X_train.shape[2]),return_sequences=True))\n",
    "    #model.add(Dropout(0.1))\n",
    "    #model.add(LSTM(number_of_units, kernel_initializer = randomInit, bias_initializer = randomInit, stateful = True,\n",
    "    #               batch_input_shape=(Batch_size,X_train.shape[1], X_train.shape[2])))\n",
    "    #model.add(Dropout(0.1))\n",
    "    model.add(Dense(Y_train.shape[1], activation='softmax'))\n",
    "    \n",
    "    nadam = optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)\n",
    "    model.compile(loss='mean_squared_error', optimizer=nadam, metrics=['accuracy'])\n",
    "\n",
    "    print(model.summary())\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def compute_metrics(predicted, Y_test):\n",
    "   \n",
    "    Y_classes = [np.argmax(item) for item in Y_test]\n",
    "    #print(Y_classes)\n",
    "    predicted_classes = [np.argmax(item) for item in predicted]\n",
    "    \n",
    "    predictions = np.array(predicted_classes)\n",
    "    Y_actual = np.array(Y_classes)\n",
    "   \n",
    "    y_actu = pd.Series(np.reshape(Y_actual,len(Y_actual)), name='Actual')\n",
    "    y_pred = pd.Series(np.reshape(predictions, len(predictions)), name='Predicted')\n",
    "    \n",
    "    y_act = pd.Categorical(y_actu, categories=[0,1,2,3,4])\n",
    "    y_pre = pd.Categorical(y_pred, categories=[0,1,2,3,4])\n",
    "    \n",
    "    #F1 score\n",
    "    from sklearn.metrics import f1_score\n",
    "    print(\"Average F1 score is {}\".format(f1_score(Y_classes, predicted_classes, average='weighted', labels = [0,1,2,3,4])))\n",
    "    \n",
    "    df_confusion = pd.crosstab(y_act, y_pre, rownames =['Actual'],colnames=['Predicted'])\n",
    "    print(\"Confusion matrix: \\n\", df_confusion)\n",
    "    #pprint.pprint(df_confusion)\n",
    "    predicted= np.array(predicted).tolist()\n",
    "    Y_test = np.array(Y_test).tolist()\n",
    "\n",
    "    n_classes = 5\n",
    "    print(\"n_classes is: \", n_classes)\n",
    "    Y_test= np.asarray(Y_test)\n",
    "    predicted = np.asarray(predicted)\n",
    "    \n",
    "    fpr = dict()\n",
    "    tpr = dict()\n",
    "    roc_auc = dict()\n",
    "    for i in range(n_classes):\n",
    "        fpr[i], tpr[i], _ = roc_curve(Y_test[:, i], predicted[:, i])\n",
    "        roc_auc[i] = auc(fpr[i], tpr[i])\n",
    "\n",
    "    # Compute micro-average ROC curve and ROC area\n",
    "    fpr[\"micro\"], tpr[\"micro\"], _ = roc_curve(Y_test.ravel(), predicted.ravel())\n",
    "    roc_auc[\"micro\"] = auc(fpr[\"micro\"], tpr[\"micro\"])\n",
    "    \n",
    "    lw = 2\n",
    "     #Compute macro-average ROC curve and ROC area\n",
    "    # first aggregate all false positive rates\n",
    "    all_fpr = np.unique(np.concatenate([fpr[i] for i in range(n_classes)]))\n",
    "\n",
    "    # Then interpolate all ROC curves at this points\n",
    "    mean_tpr = np.zeros_like(all_fpr)\n",
    "    for i in range(n_classes):\n",
    "        mean_tpr += interp(all_fpr, fpr[i], tpr[i])\n",
    "\n",
    "    # Finally average it and compute AUC\n",
    "    mean_tpr /= n_classes\n",
    "\n",
    "    fpr[\"macro\"] = all_fpr\n",
    "    tpr[\"macro\"] = mean_tpr\n",
    "    roc_auc[\"macro\"] = auc(fpr[\"macro\"], tpr[\"macro\"])\n",
    "\n",
    "    # Plot all ROC curves\n",
    "    plt.figure()\n",
    "    plt.plot(fpr[\"micro\"], tpr[\"micro\"],\n",
    "             label='micro-average ROC curve (area = {0:0.2f})'\n",
    "                   ''.format(roc_auc[\"micro\"]),\n",
    "             color='deeppink', linestyle=':', linewidth=4)\n",
    "\n",
    "    plt.plot(fpr[\"macro\"], tpr[\"macro\"],\n",
    "             label='macro-average ROC curve (area = {0:0.2f})'\n",
    "                   ''.format(roc_auc[\"macro\"]),\n",
    "             color='navy', linestyle=':', linewidth=4)\n",
    "\n",
    "    colors = cycle(['aqua', 'darkorange', 'cornflowerblue'])\n",
    "    for i, color in zip(range(n_classes), colors):\n",
    "        plt.plot(fpr[i], tpr[i], color=color, lw=lw,\n",
    "                 label='ROC curve of class {0} (area = {1:0.2f})'\n",
    "                 ''.format(i, roc_auc[i]))\n",
    "\n",
    "    plt.plot([0, 1], [0, 1], 'k--', lw=lw)\n",
    "    plt.xlim([0.0, 1.0])\n",
    "    plt.ylim([0.0, 1.05])\n",
    "    plt.xlabel('False Positive Rate')\n",
    "    plt.ylabel('True Positive Rate')\n",
    "    plt.legend(loc=\"lower right\")\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#checkpoint save weights\n",
    "#Y_train\n",
    "\n",
    "hdf5FileName = \"bestWeightsLSTMStateful3L50.hdf5\"\n",
    "checkpoint = ModelCheckpoint(hdf5FileName,monitor='val_acc',verbose=1,save_best_only=True,mode='max',save_weights_only=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class ResetStatesCallback(Callback):\n",
    "    def __init__(self):\n",
    "        self.counter = 0\n",
    "\n",
    "    def on_batch_begin(self, batch, logs={}):\n",
    "        if self.counter % (max_len*10) == 0:\n",
    "            self.model.reset_states()\n",
    "            print(\"Model reset. \",self.counter)\n",
    "            #self.counter = 0\n",
    "        self.counter += 1\n",
    "        #print(self.counter)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "lstm_1 (LSTM)                (1, 50)                   10400     \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (1, 5)                    255       \n",
      "=================================================================\n",
      "Total params: 10,655\n",
      "Trainable params: 10,655\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n",
      "None\n",
      "Train on 24880 samples, validate on 8300 samples\n",
      "Epoch 1/50\n",
      "Model reset.  0\n",
      "   19/24880 [..............................] - ETA: 14361s - loss: 0.1483 - acc: 0.5263   "
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.5/dist-packages/keras/callbacks.py:97: UserWarning: Method on_batch_begin() is slow compared to the batch update (5.219173). Check your callbacks.\n",
      "  % delta_t_median)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "24876/24880 [============================>.] - ETA: 0s - loss: 0.1343 - acc: 0.4340Epoch 00000: val_acc improved from -inf to 0.54747, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 262s - loss: 0.1343 - acc: 0.4340 - val_loss: 0.1098 - val_acc: 0.5475\n",
      "Epoch 2/50\n",
      "Model reset.  24880\n",
      "24875/24880 [============================>.] - ETA: 0s - loss: 0.1061 - acc: 0.5948Epoch 00001: val_acc improved from 0.54747 to 0.60096, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 248s - loss: 0.1061 - acc: 0.5949 - val_loss: 0.1006 - val_acc: 0.6010\n",
      "Epoch 3/50\n",
      "Model reset.  49760\n",
      "24875/24880 [============================>.] - ETA: 0s - loss: 0.0824 - acc: 0.6948Epoch 00002: val_acc improved from 0.60096 to 0.74181, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 248s - loss: 0.0824 - acc: 0.6948 - val_loss: 0.0704 - val_acc: 0.7418\n",
      "Epoch 4/50\n",
      "Model reset.  74640\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0664 - acc: 0.7641Epoch 00003: val_acc improved from 0.74181 to 0.79422, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 247s - loss: 0.0664 - acc: 0.7641 - val_loss: 0.0601 - val_acc: 0.7942\n",
      "Epoch 5/50\n",
      "Model reset.  99520\n",
      "24876/24880 [============================>.] - ETA: 0s - loss: 0.0605 - acc: 0.7881Epoch 00004: val_acc improved from 0.79422 to 0.80277, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 247s - loss: 0.0605 - acc: 0.7881 - val_loss: 0.0561 - val_acc: 0.8028\n",
      "Epoch 6/50\n",
      "Model reset.  124400\n",
      "24874/24880 [============================>.] - ETA: 0s - loss: 0.0588 - acc: 0.7961Epoch 00005: val_acc did not improve\n",
      "24880/24880 [==============================] - 247s - loss: 0.0587 - acc: 0.7962 - val_loss: 0.0582 - val_acc: 0.7936\n",
      "Epoch 7/50\n",
      "Model reset.  149280\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0574 - acc: 0.8002Epoch 00006: val_acc did not improve\n",
      "24880/24880 [==============================] - 245s - loss: 0.0574 - acc: 0.8002 - val_loss: 0.0576 - val_acc: 0.7973\n",
      "Epoch 8/50\n",
      "Model reset.  174160\n",
      "24874/24880 [============================>.] - ETA: 0s - loss: 0.0553 - acc: 0.8053Epoch 00007: val_acc improved from 0.80277 to 0.80831, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 245s - loss: 0.0553 - acc: 0.8054 - val_loss: 0.0547 - val_acc: 0.8083\n",
      "Epoch 9/50\n",
      "Model reset.  199040\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0525 - acc: 0.8190Epoch 00008: val_acc improved from 0.80831 to 0.82325, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 246s - loss: 0.0525 - acc: 0.8190 - val_loss: 0.0502 - val_acc: 0.8233\n",
      "Epoch 10/50\n",
      "Model reset.  223920\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0499 - acc: 0.8249Epoch 00009: val_acc improved from 0.82325 to 0.84482, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 245s - loss: 0.0499 - acc: 0.8249 - val_loss: 0.0457 - val_acc: 0.8448\n",
      "Epoch 11/50\n",
      "Model reset.  248800\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0466 - acc: 0.8371Epoch 00010: val_acc did not improve\n",
      "24880/24880 [==============================] - 245s - loss: 0.0466 - acc: 0.8371 - val_loss: 0.0474 - val_acc: 0.8347\n",
      "Epoch 12/50\n",
      "Model reset.  273680\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0466 - acc: 0.8393Epoch 00011: val_acc did not improve\n",
      "24880/24880 [==============================] - 245s - loss: 0.0466 - acc: 0.8393 - val_loss: 0.0469 - val_acc: 0.8355\n",
      "Epoch 13/50\n",
      "Model reset.  298560\n",
      "24874/24880 [============================>.] - ETA: 0s - loss: 0.0458 - acc: 0.8417Epoch 00012: val_acc improved from 0.84482 to 0.84639, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 246s - loss: 0.0458 - acc: 0.8417 - val_loss: 0.0460 - val_acc: 0.8464\n",
      "Epoch 14/50\n",
      "Model reset.  323440\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0455 - acc: 0.8423Epoch 00013: val_acc did not improve\n",
      "24880/24880 [==============================] - 245s - loss: 0.0455 - acc: 0.8423 - val_loss: 0.0464 - val_acc: 0.8355\n",
      "Epoch 15/50\n",
      "Model reset.  348320\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0459 - acc: 0.8426Epoch 00014: val_acc did not improve\n",
      "24880/24880 [==============================] - 244s - loss: 0.0459 - acc: 0.8426 - val_loss: 0.0478 - val_acc: 0.8331\n",
      "Epoch 16/50\n",
      "Model reset.  373200\n",
      "24874/24880 [============================>.] - ETA: 0s - loss: 0.0440 - acc: 0.8488Epoch 00015: val_acc did not improve\n",
      "24880/24880 [==============================] - 244s - loss: 0.0440 - acc: 0.8489 - val_loss: 0.0522 - val_acc: 0.8254\n",
      "Epoch 17/50\n",
      "Model reset.  398080\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0435 - acc: 0.8512Epoch 00016: val_acc improved from 0.84639 to 0.85193, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 245s - loss: 0.0435 - acc: 0.8512 - val_loss: 0.0438 - val_acc: 0.8519\n",
      "Epoch 18/50\n",
      "Model reset.  422960\n",
      "24874/24880 [============================>.] - ETA: 0s - loss: 0.0432 - acc: 0.8516Epoch 00017: val_acc did not improve\n",
      "24880/24880 [==============================] - 244s - loss: 0.0432 - acc: 0.8516 - val_loss: 0.0496 - val_acc: 0.8300\n",
      "Epoch 19/50\n",
      "Model reset.  447840\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0424 - acc: 0.8551Epoch 00018: val_acc did not improve\n",
      "24880/24880 [==============================] - 245s - loss: 0.0424 - acc: 0.8551 - val_loss: 0.0451 - val_acc: 0.8458\n",
      "Epoch 20/50\n",
      "Model reset.  472720\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0416 - acc: 0.8573Epoch 00019: val_acc did not improve\n",
      "24880/24880 [==============================] - 244s - loss: 0.0416 - acc: 0.8574 - val_loss: 0.0458 - val_acc: 0.8458\n",
      "Epoch 21/50\n",
      "Model reset.  497600\n",
      "24874/24880 [============================>.] - ETA: 0s - loss: 0.0432 - acc: 0.8510Epoch 00020: val_acc did not improve\n",
      "24880/24880 [==============================] - 243s - loss: 0.0432 - acc: 0.8511 - val_loss: 0.0455 - val_acc: 0.8434\n",
      "Epoch 22/50\n",
      "Model reset.  522480\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0427 - acc: 0.8547Epoch 00021: val_acc did not improve\n",
      "24880/24880 [==============================] - 244s - loss: 0.0427 - acc: 0.8547 - val_loss: 0.0466 - val_acc: 0.8400\n",
      "Epoch 23/50\n",
      "Model reset.  547360\n",
      "24877/24880 [============================>.] - ETA: 0s - loss: 0.0421 - acc: 0.8556Epoch 00022: val_acc did not improve\n",
      "24880/24880 [==============================] - 244s - loss: 0.0421 - acc: 0.8556 - val_loss: 0.0434 - val_acc: 0.8499\n",
      "Epoch 24/50\n",
      "Model reset.  572240\n",
      "24875/24880 [============================>.] - ETA: 0s - loss: 0.0428 - acc: 0.8518Epoch 00023: val_acc did not improve\n",
      "24880/24880 [==============================] - 243s - loss: 0.0428 - acc: 0.8518 - val_loss: 0.0442 - val_acc: 0.8466\n",
      "Epoch 25/50\n",
      "Model reset.  597120\n",
      "24877/24880 [============================>.] - ETA: 0s - loss: 0.0420 - acc: 0.8559Epoch 00024: val_acc improved from 0.85193 to 0.85530, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 244s - loss: 0.0420 - acc: 0.8559 - val_loss: 0.0428 - val_acc: 0.8553\n",
      "Epoch 26/50\n",
      "Model reset.  622000\n",
      "24875/24880 [============================>.] - ETA: 0s - loss: 0.0432 - acc: 0.8528Epoch 00025: val_acc did not improve\n",
      "24880/24880 [==============================] - 243s - loss: 0.0431 - acc: 0.8529 - val_loss: 0.0470 - val_acc: 0.8399\n",
      "Epoch 27/50\n",
      "Model reset.  646880\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0424 - acc: 0.8570Epoch 00026: val_acc did not improve\n",
      "24880/24880 [==============================] - 244s - loss: 0.0424 - acc: 0.8570 - val_loss: 0.0431 - val_acc: 0.8519\n",
      "Epoch 28/50\n",
      "Model reset.  671760\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0414 - acc: 0.8562Epoch 00027: val_acc did not improve\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "24880/24880 [==============================] - 243s - loss: 0.0414 - acc: 0.8562 - val_loss: 0.0461 - val_acc: 0.8441\n",
      "Epoch 29/50\n",
      "Model reset.  696640\n",
      "24874/24880 [============================>.] - ETA: 0s - loss: 0.0413 - acc: 0.8577Epoch 00028: val_acc improved from 0.85530 to 0.86024, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 244s - loss: 0.0412 - acc: 0.8578 - val_loss: 0.0409 - val_acc: 0.8602\n",
      "Epoch 30/50\n",
      "Model reset.  721520\n",
      "24876/24880 [============================>.] - ETA: 0s - loss: 0.0390 - acc: 0.8665Epoch 00029: val_acc did not improve\n",
      "24880/24880 [==============================] - 243s - loss: 0.0390 - acc: 0.8666 - val_loss: 0.0414 - val_acc: 0.8582\n",
      "Epoch 31/50\n",
      "Model reset.  746400\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0386 - acc: 0.8683Epoch 00030: val_acc did not improve\n",
      "24880/24880 [==============================] - 243s - loss: 0.0385 - acc: 0.8683 - val_loss: 0.0410 - val_acc: 0.8583\n",
      "Epoch 32/50\n",
      "Model reset.  771280\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0384 - acc: 0.8675Epoch 00031: val_acc improved from 0.86024 to 0.86578, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 243s - loss: 0.0384 - acc: 0.8675 - val_loss: 0.0401 - val_acc: 0.8658\n",
      "Epoch 33/50\n",
      "Model reset.  796160\n",
      "24874/24880 [============================>.] - ETA: 0s - loss: 0.0377 - acc: 0.8716Epoch 00032: val_acc did not improve\n",
      "24880/24880 [==============================] - 244s - loss: 0.0377 - acc: 0.8716 - val_loss: 0.0419 - val_acc: 0.8537\n",
      "Epoch 34/50\n",
      "Model reset.  821040\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0384 - acc: 0.8680Epoch 00033: val_acc did not improve\n",
      "24880/24880 [==============================] - 244s - loss: 0.0384 - acc: 0.8680 - val_loss: 0.0408 - val_acc: 0.8578\n",
      "Epoch 35/50\n",
      "Model reset.  845920\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0400 - acc: 0.8641Epoch 00034: val_acc did not improve\n",
      "24880/24880 [==============================] - 233s - loss: 0.0400 - acc: 0.8641 - val_loss: 0.0443 - val_acc: 0.8522\n",
      "Epoch 36/50\n",
      "Model reset.  870800\n",
      "24877/24880 [============================>.] - ETA: 0s - loss: 0.0398 - acc: 0.8647Epoch 00035: val_acc improved from 0.86578 to 0.86663, saving model to bestWeightsLSTMStateful3L50.hdf5\n",
      "24880/24880 [==============================] - 227s - loss: 0.0397 - acc: 0.8647 - val_loss: 0.0396 - val_acc: 0.8666\n",
      "Epoch 37/50\n",
      "Model reset.  895680\n",
      "24873/24880 [============================>.] - ETA: 0s - loss: 0.0376 - acc: 0.8693Epoch 00036: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0376 - acc: 0.8694 - val_loss: 0.0418 - val_acc: 0.8577\n",
      "Epoch 38/50\n",
      "Model reset.  920560\n",
      "24877/24880 [============================>.] - ETA: 0s - loss: 0.0381 - acc: 0.8678Epoch 00037: val_acc did not improve\n",
      "24880/24880 [==============================] - 228s - loss: 0.0381 - acc: 0.8678 - val_loss: 0.0445 - val_acc: 0.8505\n",
      "Epoch 39/50\n",
      "Model reset.  945440\n",
      "24875/24880 [============================>.] - ETA: 0s - loss: 0.0391 - acc: 0.8658Epoch 00038: val_acc did not improve\n",
      "24880/24880 [==============================] - 228s - loss: 0.0391 - acc: 0.8658 - val_loss: 0.0422 - val_acc: 0.8537\n",
      "Epoch 40/50\n",
      "Model reset.  970320\n",
      "24876/24880 [============================>.] - ETA: 0s - loss: 0.0385 - acc: 0.8674Epoch 00039: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0385 - acc: 0.8674 - val_loss: 0.0428 - val_acc: 0.8570\n",
      "Epoch 41/50\n",
      "Model reset.  995200\n",
      "24876/24880 [============================>.] - ETA: 0s - loss: 0.0408 - acc: 0.8590Epoch 00040: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0408 - acc: 0.8590 - val_loss: 0.0421 - val_acc: 0.8575\n",
      "Epoch 42/50\n",
      "Model reset.  1020080\n",
      "24874/24880 [============================>.] - ETA: 0s - loss: 0.0397 - acc: 0.8633Epoch 00041: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0397 - acc: 0.8633 - val_loss: 0.0457 - val_acc: 0.8440\n",
      "Epoch 43/50\n",
      "Model reset.  1044960\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0412 - acc: 0.8565Epoch 00042: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0412 - acc: 0.8565 - val_loss: 0.0425 - val_acc: 0.8571\n",
      "Epoch 44/50\n",
      "Model reset.  1069840\n",
      "24877/24880 [============================>.] - ETA: 0s - loss: 0.0424 - acc: 0.8532Epoch 00043: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0424 - acc: 0.8532 - val_loss: 0.0474 - val_acc: 0.8377\n",
      "Epoch 45/50\n",
      "Model reset.  1094720\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0416 - acc: 0.8581Epoch 00044: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0416 - acc: 0.8581 - val_loss: 0.0437 - val_acc: 0.8496\n",
      "Epoch 46/50\n",
      "Model reset.  1119600\n",
      "24877/24880 [============================>.] - ETA: 0s - loss: 0.0397 - acc: 0.8643Epoch 00045: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0396 - acc: 0.8643 - val_loss: 0.0450 - val_acc: 0.8434\n",
      "Epoch 47/50\n",
      "Model reset.  1144480\n",
      "24875/24880 [============================>.] - ETA: 0s - loss: 0.0411 - acc: 0.8591Epoch 00046: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0410 - acc: 0.8592 - val_loss: 0.0509 - val_acc: 0.8270\n",
      "Epoch 48/50\n",
      "Model reset.  1169360\n",
      "24875/24880 [============================>.] - ETA: 0s - loss: 0.0404 - acc: 0.8611Epoch 00047: val_acc did not improve\n",
      "24880/24880 [==============================] - 227s - loss: 0.0404 - acc: 0.8611 - val_loss: 0.0424 - val_acc: 0.8589\n",
      "Epoch 49/50\n",
      "Model reset.  1194240\n",
      "24878/24880 [============================>.] - ETA: 0s - loss: 0.0414 - acc: 0.8583Epoch 00048: val_acc did not improve\n",
      "24880/24880 [==============================] - 226s - loss: 0.0414 - acc: 0.8583 - val_loss: 0.0447 - val_acc: 0.8475\n",
      "Epoch 50/50\n",
      "Model reset.  1219120\n",
      "24879/24880 [============================>.] - ETA: 0s - loss: 0.0425 - acc: 0.8547Epoch 00049: val_acc did not improve\n",
      "24880/24880 [==============================] - 226s - loss: 0.0425 - acc: 0.8547 - val_loss: 0.0469 - val_acc: 0.8414\n",
      "\n",
      "\n",
      "--- Time for training : 11999.730452537537 seconds ---\n"
     ]
    }
   ],
   "source": [
    "#Time to train\n",
    "\n",
    "Batch_size=1\n",
    "start_time = time.time()\n",
    "\n",
    "x_train,y_train = processTrainTestArrays(X_train,Y_train)\n",
    "x_val,y_val = processTrainTestArrays(X_val,Y_val)\n",
    "model = create_model(x_train,y_train, 50)\n",
    "\n",
    "x = np.expand_dims(np.expand_dims(x_train.flatten(), axis=1), axis=1)\n",
    "\n",
    "x_val = np.expand_dims(np.expand_dims(x_val.flatten(), axis=1), axis=1)\n",
    "model.fit(x, y_train, epochs=50, batch_size=Batch_size, verbose=1, shuffle=False,\n",
    "            validation_data = (x_val,y_val),callbacks=[checkpoint,ResetStatesCallback()])\n",
    "\n",
    "\n",
    "print(\"\\n\\n--- Time for training : %s seconds ---\" % (time.time() - start_time))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "===========================\n",
      "Time for testing\n",
      "===========================\n",
      "\n",
      "Optimal weights loaded from file bestWeightsLSTMStateful3L50.hdf5\n",
      "Model Successfully compiled with loaded weights\n",
      "\n",
      "8300/8300 [==============================] - 21s    \n",
      "Loss for testing = 0.03811505821068982 and Accuracy for testing = 0.8734939759036144\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/bwang/.local/lib/python3.5/site-packages/sklearn/metrics/classification.py:1135: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Average F1 score is 0.646220986703234\n",
      "Confusion matrix: \n",
      " Predicted    0    1    2   3\n",
      "Actual                      \n",
      "0          191    9    0   0\n",
      "1            2  195    2   1\n",
      "2            4   93  103   0\n",
      "3            0    9  152  65\n",
      "4            0    2    2   0\n",
      "n_classes is:  5\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nsnNn8+um+UJWcbPAe8BFYDXq/eXV3Mbg5uVWMyWP4vUHRhI/IrvfU/Mnto99YNPDh2/J8uUn8tui\nbNlyNE5e/DFCvE7FS0mjUbtgriKyUERic9lvbmTGHwf0SYlyNfiUHDx4UPbv3y8njh4SQ9zdwrHl\nEaW3s6N06dLa/wcMGCDTpk0TEVWI0NHRUbZs2SIiqvhh586dZd68eSIicvLkSXF0dJSzZ89qNi5Y\nsCBPbcsL+e8XXnghk9Bhfp/zYTh9+rR4e3tLQkKCXLp0SRwdHR/4fffs2VOWLFkiImpOjdFoFBGR\n48ePi6urq9Zu0KBBmoR8RvI6jyI7R3EaKJ3y/8rAwdyeJC+3VEcxIbsrnRcs8VYdxeWt+X2mR8Io\nIkvCkqX25UQhnYNoLyK/i8ijVl3I+IODKSZbVnz99SGTdsOGbczV+S9fviyurq4ycOBAcXFxkZde\nekn+/PNPadasmTg7O8u///4rIiL//vuvNG3aVHx9fSUgIEDOnTsnIuoN7s033xRPT0/x8vKSOXPm\nyN3b16R69eoyYMAAcXV1lXmzP5dDBw9IkyZNxMvLS55//nm5d++eWXu6d+8uDRs2FA8PD/n6669F\nRK3jMGFC2i8yvZLtsmXLxN/fX3x8fGT48OHaTaJ06dLyxhtviLe3t+zevVs++ugjadSokXh6esqw\nYcO0m8OBAwfEy8tLfHx8ZMKECeLp6al9rgkTJkijRo3Ey8tLFi1aZNbe9I5i4cKFMnLkSBER+fbb\nb+WVV14xaXvhwgWpWbOmiIi88sor8t133z3w+4mOjpZBgwaJTqcTLy8vWbNmTabzrl69WgYOHCgi\nqqrra6+9Jo0bN5bx48dLnTp1JCIiQmvr7Owst2/fljt37kjPnj2lUaNG0qhRI7M3xPv370v9+vW1\n/ax+Az/88IN07dpV2rRpIy1bthQRkRkzZmjX7oMPPtD6MPf9PgqffPKJfPLJJ9p+x44dZe/evVm2\nT1XxTa0Jkp69e/eaKAavX79e+z4zUpCO4kiG/cO5PUlebg4pjmKi2cuTR0RdVZ3EHDuR5IT8PFOu\nSRCRIBHR6dOcQzGDUV4Vkbwc2xQFR5ETmfGoqCjtafHPP/+Unj17iojIggULpFevXpKcnCz6xFg5\nsGeXHDx4UKpXry5vvj5WYqPUUYSXl5dWLGby5Mkybtw4s/aYkwa/c+eOODk5aW06d+4su3fvljNn\n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\n+vXTpILs7e1p06YNmzdv1hzFkywznn+LzvAC6nRT6v4rwLxs2s8DJmXx2nDgEHAIPz/JconvfqLI\nPzdEFhwR2XZFZF13dSH7+Nc5Wf/JlpAIvYxZrC5ebzka98j95Zbda+eLp0MJbbG6b8vacutCFrXB\n84Citph95MgRqV27tiQnJ0tcXJzUq1dP/vzzTxFRF7e7dOkiX331lYiIHD9+XJycnOS///4TERGD\nwaAphKbnnXfekXHj0hSFUxdunZyc5MyZM2IwGKRnz57ZqsdOmDBBXn75ZXn22We1Y/369ZMZM2Zo\n+0ePHs107i+//FJeffVVERH577//pHbt2pKQkJCtemyfPn1k1qxZIqIuBkdGRppcp9mzZ8uYMWNE\nRGTHjh0CyOXLl+XmzZsSHx8vIqqqbvfu3SU6OlpbrI2MjJQKFSpkOt/Vq1fFyclJ9uzZY9aeVJo0\naSLBwcEiIrJ+/XoJDAwUEbXudIkSJcyqxyYmJoqTk5OmgJuUlCSnTp0SEZGKFStKaGioJCUlSfv2\n7fNEPTbjYvbvv/+eqc2ZM2ekbdu2kpycLLGxseLp6SknT56UO3fuSEREhIiov7VnnnlGfv31V+19\nOp1OQkJCHtnGvCCvF7OLhKNAHUnsB0o8sF8/P6mfkyuVHK9JZsv9Gzl5R5YkJBnlwxWRMnT+XVm4\n+b6JjHVBce/mBRnSqb7mIJwq28iWJZ/k+3mLmqMQsciMF7TM+JAhQ8Te3l58fHzEx8dH/Pz8zNr1\npMiMi4jMmDFD3N3dxdPTU3PKx48fF19fX/Hy8hJPT0/56KOPtPZPusx4fjqKAGBLuv13gXfNtGsP\nnAWq5KhfPz9xz8mVurRJdRJLG+SkdZYYjUZZvDVahs6/K5OWR0h8YgE7CaNR5FSQhH9WQSqVRopZ\nI5MHtZC4qLsFcvqi4CgsPB7cunVL2rdvX9hmFAozZ86Ub7/9trDN0HicwmMPAi6KotQDbgJ9gZfS\nN1AUpQHwNdBZRO5k7sI8OZqFz6Ns7J2n0pLqRhZwUt25/b9T78JnlAjdTUVrWD7Oh9pdP8Gtad7r\nVVmw8KiklxnPbjH+ScTe3p5XXnmlsM3IN/LNUYiIXlGUMcAW1Hv79yJyWlGUj1E920bgc8AOWJ2y\ncHhNRLpl2WkKD3QUInmiFnshJJmf98QBMLBNaWpUKJiF4riou/zf/7rx+U97mdweJnerDK1n0tG9\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f895d2b4940>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Test with best model\n",
    "#Load weights and compile again\n",
    "print(\"\\n===========================\\nTime for testing\\n===========================\\n\")\n",
    "model.load_weights(hdf5FileName)\n",
    "nadam = optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)\n",
    "model.compile(loss='mean_squared_error', optimizer=nadam, metrics=['accuracy'])\n",
    "print(\"Optimal weights loaded from file {}\".format(hdf5FileName))\n",
    "print(\"Model Successfully compiled with loaded weights\\n\")\n",
    "\n",
    "#Do same preprocessing for test data\n",
    "x_test,y_test = processTrainTestArrays(X_test,Y_test)\n",
    "x_test = np.expand_dims(np.expand_dims(x_test.flatten(), axis=1), axis=1)\n",
    "\n",
    "loss,acc = model.evaluate(x_test,y_test,batch_size=Batch_size)\n",
    "print(\"Loss for testing = {} and Accuracy for testing = {}\".format(loss,acc))\n",
    "\n",
    "predicted = model.predict(x_test,batch_size=Batch_size)\n",
    "\n",
    "X_test = np.asarray(X_test)\n",
    "temp = np.reshape(predicted,(Y_test.shape[0],X_test.shape[1],Y_test.shape[1]))\n",
    "temp1 = [np.argmax(item1) for item in temp for item1 in item]\n",
    "temp1 = np.reshape(np.asarray(temp1),(Y_test.shape[0],X_test.shape[1],1))\n",
    "temp1 = [np.floor(np.mean(item)) for item in temp1]\n",
    "temp1 = onehotencode(temp1)\n",
    "\n",
    "\n",
    "compute_metrics(temp1, Y_test)    \n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
